package com.ruowei.modules.foodOrder.web.rest;

import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ruowei.common.error.exception.CommonException;
import com.ruowei.common.lang.StringUtils;
import com.ruowei.modules.foodOrder.domain.MerchandiseType;
import com.ruowei.modules.foodOrder.domain.QMerchandiseType;
import com.ruowei.modules.foodOrder.repository.MerchandiseRepository;
import com.ruowei.modules.foodOrder.web.dto.AddMerchandiseTypeDTO;
import com.ruowei.modules.foodOrder.repository.MerchandiseTypeRepository;
import com.ruowei.modules.foodOrder.web.dto.UpdateMerchandiseTypeDTO;
import com.ruowei.modules.sys.repository.SysUserRepository;
import com.ruowei.modules.sys.utils.CommonUtils;
import com.ruowei.security.CurrentUser;
import com.ruowei.security.UserModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

/**
 * REST controller for managing {@link MerchandiseType}.
 */
@RestController
@RequestMapping("/api")
@Transactional
@Api(tags = "商品分类")
public class MerchandiseTypeResource {

    private final Logger log = LoggerFactory.getLogger(MerchandiseTypeResource.class);

    private final MerchandiseRepository merchandiseRepository;
    private final MerchandiseTypeRepository merchandiseTypeRepository;
    private final SysUserRepository sysUserRepository;
    private final JPAQueryFactory queryFactory;

    private final QMerchandiseType qMerchandiseType = QMerchandiseType.merchandiseType;

    public MerchandiseTypeResource(MerchandiseRepository merchandiseRepository, MerchandiseTypeRepository merchandiseTypeRepository, SysUserRepository sysUserRepository, JPAQueryFactory queryFactory) {
        this.merchandiseRepository = merchandiseRepository;
        this.merchandiseTypeRepository = merchandiseTypeRepository;
        this.sysUserRepository = sysUserRepository;
        this.queryFactory = queryFactory;
    }

    @PostMapping("/createMerchandiseType")
    @ApiOperation(value = "新增商品分类")
    public ResponseEntity<MerchandiseType> createMerchandiseType(@RequestBody AddMerchandiseTypeDTO dto,
                                                                 @ApiIgnore @CurrentUser UserModel userModel) {
        if (merchandiseTypeRepository.existsByTypeNameAndMerchantCodeAndStatus(dto.getTypeName(), dto.getMerchantCode(), true)) {
            throw new CommonException("不能重复添加");
        }
        MerchandiseType merchandiseType = new MerchandiseType();
        merchandiseType.setTypeCode(CommonUtils.getUUID());
        merchandiseType.setTypeName(dto.getTypeName());
        merchandiseType.setMerchantCode(dto.getMerchantCode());
        merchandiseType.setSort(dto.getSort());
        merchandiseType.setRemark(dto.getRemark());
        merchandiseType.setStatus(true);
        merchandiseType.setCreateTime(Instant.now());
        merchandiseTypeRepository.save(merchandiseType);

        return ResponseEntity.ok(merchandiseType);
    }


    @PostMapping("/updateMerchandiseType")
    @ApiOperation(value = "修改商品分类")
    public ResponseEntity<MerchandiseType> updateMerchandiseType(@RequestBody UpdateMerchandiseTypeDTO dto,
                                                                 @ApiIgnore @CurrentUser UserModel userModel) {
        Optional<MerchandiseType> codeOpt = merchandiseTypeRepository.findOneByTypeCodeAndStatus(dto.getTypeCode(), true);
        if (!codeOpt.isPresent()) {
            throw new CommonException("该商品分类不存在");
        }
        Optional<MerchandiseType> nameOpt = merchandiseTypeRepository.findOneByMerchantCodeAndTypeNameAndStatus(codeOpt.get().getMerchantCode(), dto.getTypeName(), true);
        if (nameOpt.isPresent() && !nameOpt.get().getTypeCode().equals(dto.getTypeCode())) {
            throw new CommonException("商品分类不能重复添加");
        }
        MerchandiseType merchandiseType = codeOpt.get();
        if (StringUtils.isNotEmpty(dto.getTypeName())) {
            merchandiseType.setTypeName(dto.getTypeName());
        }
        if (StringUtils.isNotEmpty(dto.getParentCode())) {
            merchandiseType.setParentCode(dto.getParentCode());
        }
        if (dto.getLevel() != null) {
            merchandiseType.setLevel(dto.getLevel());
        }
        if (dto.getSort() != null) {
            merchandiseType.setSort(dto.getSort());
        }
        if (StringUtils.isNotEmpty(dto.getRemark())) {
            merchandiseType.setRemark(dto.getRemark());
        }
        merchandiseTypeRepository.save(merchandiseType);

        return ResponseEntity.ok(merchandiseType);
    }


    @GetMapping("/getMerchandiseTypeList")
    @ApiOperation(value = "查询商品分类列表")
    public ResponseEntity<List<MerchandiseType>> getMerchandiseTypeList(@RequestParam String merchantCode,
                                                                        @ApiIgnore @CurrentUser UserModel userModel) {
        List<MerchandiseType> result = queryFactory.selectFrom(qMerchandiseType)
            .where(qMerchandiseType.merchantCode.eq(merchantCode)
                .and(qMerchandiseType.status.eq(true)))
            .orderBy(qMerchandiseType.sort.asc())
            .fetch();

        return ResponseEntity.ok(result);
    }


    @PostMapping("/deleteMerchandiseType")
    @ApiOperation(value = "删除商品分类")
    public ResponseEntity<Void> deleteMerchandiseType(@RequestParam String typeCode,
                                                      @ApiIgnore @CurrentUser UserModel userModel) {
        Optional<MerchandiseType> opt = merchandiseTypeRepository.findOneByTypeCodeAndStatus(typeCode, true);
        if (!opt.isPresent()) {
            throw new CommonException("该商品分类不存在");
        }
        MerchandiseType merchandiseType = opt.get();
        merchandiseType.setStatus(false);
        merchandiseTypeRepository.save(merchandiseType);
        //删除该分类下的商品
        merchandiseRepository.saveAll(merchandiseRepository.findAllByTypeCodeAndDeleteStatus(typeCode, false).stream()
            .peek(merchandise -> {
                if (merchandise.isPublishStatus()) {
                    throw new CommonException("分类下有商品未下架，无法删除");
                }
                merchandise.setDeleteStatus(true);
            }).collect(Collectors.toList()));
        return ResponseEntity.ok().build();
    }
}
